﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YJKStairs.CommonUnit;
using YJKStairs.HYElevator.DataInfo;
using YJKStairs.HYElevator.Kit;
using YJKStairs.HYElevator.ShowForm;

namespace YJKStairs.HYElevator.Manage
{
	internal class ElevatorManger
	{
		public ElevatorManger(ExternalCommandData commandData)
		{
			this.m_CmdData = commandData;
			this.m_Doc = commandData.Application.ActiveUIDocument.Document;
		}

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public Result Run()
		{
			ElevSettingsFrm elevSettingsFrm = null;
			Result result;
			try
			{
				List<ViewPlan> list = new List<ViewPlan>();
				this.GetFloorViewPlans(out list);
				if (list.Count == 0)
				{
					YJKMessageBox.Show("没有楼层信息!");
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
				else
				{
					elevSettingsFrm = new ElevSettingsFrm(this.m_Doc);
					elevSettingsFrm.Show(CmdPutElevator._hWndRevit);
					ElevatorSettingParam elevatorSettingParam = new ElevatorSettingParam();
					int wMsg = 7;
					ElevatorManger.SendMessage(CmdPutElevator._hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
					for (;;)
					{
						elevSettingsFrm.RefreshMaxNum();
						XYZ item;
						XYZ item2;
						XYZ item3;
						if (!this.GetThreePoints(list, out item, out item2, out item3))
						{
							break;
						}
						BaseParam baseParam = elevSettingsFrm.GetBaseParam();
						LiftCarParam carParam = elevSettingsFrm.GetCarParam();
						DoorParam doorParam = elevSettingsFrm.GetDoorParam();
						OtherParam otherParam = elevSettingsFrm.GetOtherParam();
						elevatorSettingParam.m_baseParam = baseParam;
						elevatorSettingParam.m_doorParam = doorParam;
						elevatorSettingParam.m_liftCarParam = carParam;
						elevatorSettingParam.m_otherParam = otherParam;
						elevatorSettingParam.isAlarm = elevSettingsFrm.GetAlarmInfo();
						SelectFloorForm selectFloorForm = new SelectFloorForm(list);
						if (selectFloorForm.ShowDialog() != DialogResult.OK)
						{
							goto Block_5;
						}
						Dictionary<ViewPlan, bool> levelStatus = selectFloorForm.LevelStatus;
						List<XYZ> list2 = new List<XYZ>();
						list2.Add(item);
						list2.Add(item2);
						list2.Add(item3);
						new SetElevator(this.m_CmdData, elevatorSettingParam, levelStatus, list2).Execute();
					}
					elevSettingsFrm.SaveSettings();
					elevSettingsFrm.Close();
					return Autodesk.Revit.UI.Result.Succeeded;
					Block_5:
					elevSettingsFrm.SaveSettings();
					elevSettingsFrm.Close();
					result = Autodesk.Revit.UI.Result.Failed;
				}
			}
			catch (Exception)
			{
				elevSettingsFrm.SaveSettings();
				elevSettingsFrm.Close();
				result = Autodesk.Revit.UI.Result.Failed;
			}
			return result;
		}

		private bool GetThreePoints(List<ViewPlan> FloorPlan, out XYZ pt1, out XYZ pt2, out XYZ pt3)
		{
			pt1 = new XYZ();
			pt2 = new XYZ();
			pt3 = new XYZ();
			bool result;
			try
			{
				for (;;)
				{
					Selection selection = this.m_CmdData.Application.ActiveUIDocument.Selection;
					pt1 = selection.PickPoint((Autodesk.Revit.UI.Selection.ObjectSnapTypes)16, "选择墙上第一点:");
					pt2 = selection.PickPoint((Autodesk.Revit.UI.Selection.ObjectSnapTypes)16, "选择墙上第二点:");
					Autodesk.Revit.DB.View activeView = this.m_Doc.ActiveView;
					List<WallLocation> list = FilterWallByEachLayer.GetInstance(this.m_Doc, FloorPlan).DicWallEachLayer[activeView.GenLevel.Id];
					Line line = Line.CreateBound(pt1, pt2);
					XYZ xyz = line.Evaluate(0.1, true);
					XYZ xyz2 = line.Evaluate(0.9, true);
					line = Line.CreateBound(xyz, xyz2);
					foreach (WallLocation wallLocation in list)
					{
						double offestValue = (this.m_Doc.GetElement(wallLocation.WallId) as Wall).Width + 0.2;
						if (CurveLoopSplit.IsCurvCrossCurve(line, wallLocation.curve, offestValue))
						{
							pt3 = selection.PickPoint((Autodesk.Revit.UI.Selection.ObjectSnapTypes)0, "选择电梯的方向:");
							return true;
						}
					}
					YJKMessageBox.Show("所选的点不在墙上,请重新选择！");
				}
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		public void GetFloorViewPlans(out List<ViewPlan> ViewPlans)
		{
			List<Level> sortLevels = Common.GetSortLevels(this.m_Doc, double.MinValue, double.MaxValue);
			List<ViewPlan> list = new List<ViewPlan>();
			List<double> list2 = new List<double>();
			foreach (Element element in new FilteredElementCollector(this.m_Doc).OfClass(typeof(ViewPlan)))
			{
				ViewPlan viewPlan = element as ViewPlan;
				if (viewPlan != null && (int)viewPlan.ViewType == 1 && viewPlan.GenLevel != null)
				{
					list2.Add(viewPlan.GenLevel.Elevation);
					list.Add(viewPlan);
				}
			}
			List<ViewPlan> list3 = new List<ViewPlan>();
			for (int i = 0; i < sortLevels.Count; i++)
			{
				for (int j = 0; j < list2.Count; j++)
				{
					if (Geometry.IsEqual(sortLevels[i].Elevation, list2[j]))
					{
						list3.Add(list[j]);
					}
				}
			}
			ViewPlans = list3.Distinct(new LevelEqualityComparer()).ToList<ViewPlan>();
		}

		private ExternalCommandData m_CmdData;

		private Document m_Doc;
	}
}
